package cn.mdmm.service.impl.user;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.mdmm.common.MessageConstant;
import cn.mdmm.entity.response.ResponseBodyToOne;
import cn.mdmm.entity.system.SysRole;
import cn.mdmm.entity.system.SysRoleUser;
import cn.mdmm.entity.system.SysUser;
import cn.mdmm.entity.user.request.UserRequest;
import cn.mdmm.entity.user.request.UserUpdatePwdRequest;
import cn.mdmm.mapper.system.SysRoleUserMapper;
import cn.mdmm.mapper.user.UserMapper;
import cn.mdmm.service.system.SysRoleService;
import cn.mdmm.service.user.UserCodeInfoService;
import cn.mdmm.service.user.UserService;
import cn.modoumama.common.exception.RequiredException;
import cn.modoumama.common.exception.ServiceException;
import cn.modoumama.common.response.Response;
import cn.modoumama.common.utils.PasswordUtils;
import cn.modoumama.common.utils.StringUtils;
import cn.modoumama.service.base.impl.BaseServiceImpl;
import net.spy.memcached.MemcachedClient;

@Service
@Transactional
public class UserServiceImpl extends BaseServiceImpl<SysUser, Long>implements UserService {
	Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private SysRoleUserMapper roleUsermapper;
	@Autowired
	private UserCodeInfoService userCodeInfoService;
	@Autowired
	private SysRoleUserMapper sRoleUserMapper;
	@Autowired
	SysRoleService sysRoleService;
	@Autowired
	MemcachedClient memcachedClient;
	@Autowired
	public void setMapper(UserMapper mapper) {
		setGenericMapper(mapper);
	}
	
	 /**
     * 用户登陆的token,保存用户的信息
     */
    public static final String token_key = "token_key_";
    /**
     * 保存的用户登陆的token信息，后面接userId
     */
    public static final String user_token = "user_token_";
	
	@Override
	public Integer insert(SysUser record){
		int count = 0;
		if(StringUtils.isBlank(record.getPhone())){
			throw new RequiredException("phone");
		}

		record.setUserStatus(1);
		record.setCreateTime(new Date());
		record.setUpdateTime(new Date());
		record.setUserPwd(PasswordUtils.getPassword(record.getUserType(), record.getUserPwd()));
		count = super.insert(record);
		return count;
	}
	@Override
	public List<SysRoleUser> getRoleIds(Long userId){
		SysRoleUser roleUser = new SysRoleUser();
		roleUser.setUserId(userId);
		List<SysRoleUser> roleUsers= roleUsermapper.getListByModel(roleUser);
		return roleUsers;
	}
	
	@Override
	public Integer updateById(SysUser record){
		record.setUpdateTime(new Date());
		int flag = super.updateById(record);
		return flag;
	}
	
	@Override
	public void updateUserPwd(Long id,String userPwd,String newPwd,String confirmPwd) {
		SysUser user = new SysUser();
		user.setId(id);
		SysUser record = getObjectByModel(user);
		if(StringUtils.isNotBlank(userPwd)){
			userPwd = PasswordUtils.getPassword(record.getUserType(), userPwd);
			if(!userPwd.equals(record.getUserPwd())){
				throw new ServiceException(MessageConstant.PASSWORD_ERROR);
			}
		}
		
		if(newPwd.equals(confirmPwd)){
			newPwd = PasswordUtils.getPassword(record.getUserType(), newPwd);
			record.setUserPwd(newPwd);
			record.setUpdateTime(new Date());
			super.updateById(record);
			
		}else{
			throw new ServiceException(MessageConstant.NEW_PASSWORD_DIVERSE);
		}
	}
	
	@Override
	public  Integer removeByIds(Long[] userIds){
		int count = 0;
		for(Long userId : userIds){
			//删除用户
			removeById(userId);
			//删除用户和角色的绑定关系
			Map<String, Object> condition = new HashMap<String, Object>();
			condition.put("userId", userId);					
			count = roleUsermapper.deleteByCondition(condition);
		}
		return count;
	}

	@Override
	public Response checkUser(UserRequest request) {
		Response response = new Response();
		SysUser sysUser = copyValue(request);
		sysUser = getObjectByModel(sysUser);
		if(sysUser != null){
			throw new ServiceException(MessageConstant.USER_DOES_IS_EXIST);
		}
		return response;
	}

	@Override
	public ResponseBodyToOne register(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		String code = request.getCode();
		String phone = request.getPhone();
		if(StringUtils.isBlank(code)){
			throw new RequiredException("code");
		}
		if(StringUtils.isBlank(phone)){
			throw new RequiredException("phone");
		}
		userCodeInfoService.verificationCode(phone, code);
		
		SysUser sysUser = new SysUser();
		if(StringUtils.isNotBlank(request.getUserName())){
			sysUser.setUserName(request.getUserName());
			sysUser = getObjectByModel(sysUser);
			if(sysUser != null){
				throw new ServiceException(MessageConstant.LOGIN_NAME_DOES_IS_EXIST);
			}
		}
		if(StringUtils.isNotBlank(request.getEmail())){
			sysUser.setEmail(request.getEmail());
			sysUser = getObjectByModel(sysUser);
			if(sysUser != null){
				throw new ServiceException(MessageConstant.EMAIL_DOES_IS_EXIST);
			}
		}
		
		//设置默认登陆名为手机号
		if(StringUtils.isBlank(request.getUserName())){
			request.setUserName(phone);
		}
		

		sysUser = copyValue(request);
		sysUser.setUserType(3);
		//设置默认密码为手机号
		if(StringUtils.isBlank(sysUser.getUserPwd())){
			sysUser.setUserPwd(phone);
		}
		insert(sysUser);
		responseBodyToOne.setData(getUser(sysUser));
		return responseBodyToOne;
	}

	@Override
	public ResponseBodyToOne login(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = null;
		if(StringUtils.isNotBlank(request.getPhone())){
			if(StringUtils.isNotBlank(request.getCode())){
				userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
				user = new SysUser();
				user.setPhone(request.getPhone());
				user = getObjectByModel(user);
			}else if(StringUtils.isNotBlank(request.getUserPwd())){
				user= getUser(request.getPhone(), null, request.getUserPwd());
			}else{
				throw new RequiredException("code");
			}
		}else if(StringUtils.isBlank(request.getUserName())){
			throw new RequiredException("phone");
		}else if(StringUtils.isBlank(request.getUserPwd())){
				throw new RequiredException("userPwd");
		}else{
			user = getUser(request.getPhone(), request.getUserName(), request.getUserPwd());
		}
		
		if(user == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}else{
			//当前token
            String token = StringUtils.getToken();
			 //保存用户的唯一token
            saveToken(user, token);
            user.setToken(token);
			responseBodyToOne.setData(getUser(user));
		}
		
		return responseBodyToOne;
	}
	
	private SysUser getUser(String phone, String userName, String userPwd){
		SysUser user = new SysUser();
		if(StringUtils.isNotBlank(phone)){
			user.setPhone(phone);
		}else if(StringUtils.isNotBlank(userName)){
			user.setUserName(userName);
		}
		user = getObjectByModel(user);
		if(user == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		if(!user.getUserPwd().equals(PasswordUtils.getPassword(user.getUserType(), userPwd))){
			throw new ServiceException(MessageConstant.PASSWORD_ERROR);
		}
		
		return user;
	}

	private SysUser copyValue(UserRequest request){
		SysUser user = new SysUser();
		try {
			PropertyUtils.copyProperties(user, request);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			logger.info("");
		}
		
		return user;
	}

	@Override
	public Response updatePwd(UserUpdatePwdRequest request) {
		Response response = new Response();
		if(StringUtils.isBlank(request.getNewPwd())){
			throw new RequiredException("newPwd");
		}
		if(StringUtils.isBlank(request.getConfirmPwd())){
			throw new RequiredException("confirmPwd");
		}
		updateUserPwd(request.getUserId(), request.getUserPwd(), request.getNewPwd(), request.getConfirmPwd());
		return response;
	}
	
	@Override
	public Response resetPwd(UserUpdatePwdRequest request){
		Response response = new Response();
		if(StringUtils.isBlank(request.getPhone())){
			throw new RequiredException("phone");
		}
		
		if(StringUtils.isBlank(request.getCode())){
			throw new RequiredException("code");
		}
		
		if(StringUtils.isBlank(request.getNewPwd())){
			throw new RequiredException("newPwd");
		}
		if(StringUtils.isBlank(request.getConfirmPwd())){
			throw new RequiredException("confirmPwd");
		}
		
		SysUser sysUser = new SysUser();
		sysUser.setPhone(request.getPhone());
		sysUser = getObjectByModel(sysUser);
		if(sysUser == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		updateUserPwd(sysUser.getId(), null, request.getNewPwd(), request.getConfirmPwd());

		//验证验证码
		userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
		return response;
	}
	
	@Override
	public ResponseBodyToOne updateUser(UserRequest request){
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = new SysUser();
		user.setId(request.getUserId());
		user = getObjectByModel(user);
		user.setRealName(request.getRealName());
		user.setSex(request.getSex());
		user.setHeadImgUrl(request.getHeadImgUrl());
		updateById(user);
		responseBodyToOne.setData(getUser(user));
		return responseBodyToOne;
	}
	


	public void  bindRoleUser(Long userId,Long[] roleIds){
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("userId", userId);
		sRoleUserMapper.deleteByCondition(condition);
		for(int i=0;i<roleIds.length;i++){
			SysRole role = sysRoleService.getRole(roleIds[i]);
			if(role == null || role.getRoleType()<1){
				continue;
			}
			if(roleIds[i]!=1 && roleIds[i]!=2){
				SysRoleUser record = new SysRoleUser();
				record.setRoleId(roleIds[i]);
				record.setUserId(userId);
				sRoleUserMapper.insertModel(record);
			}
			
		}
	}

	@Override
	public List<SysRole> getAllRole(Long userId) {
		SysUser sysUser = findById(userId);
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("roleType", sysUser.getUserType());
		List<SysRole> roles = sysRoleService.findModelsByCondition(condition);

   		List<SysRoleUser> roleUsers = getRoleIds(userId);
   		//获取SysRole的id集合
		Set<Long> roleIds = new HashSet<>();
		for (SysRoleUser roleUser1 : roleUsers) {
			roleIds.add(roleUser1.getRoleId());
		}
		//设置用户是否正在使用
   		for (Iterator<SysRole> iterator = roles.iterator(); iterator.hasNext();) {
   			SysRole role = iterator.next();
			if(roleIds.contains(role.getRoleId())){
				role.setIsUse(true);
   			}else{
   				role.setIsUse(false);
   			}
		}
		return roles;
	}
	
	/** 接口返回数据前，去掉密码和创建时间*/
	private SysUser getUser(SysUser user){
		user.setUserPwd(null);
		user.setCreateTime(null);
		user.setUpdateTime(null);
		return user;
	}
	
	/**
     * <p>保存用户的唯一token</p>
     *
     * @param user
     * @param token
     * @return 创建人：邓强   <br>
     * 创建时间：2017年7月18日 下午4:28:11    <br>
	 * @throws ExecutionException 
	 * @throws InterruptedException 
     */
    private void saveToken(SysUser user, String token){
        //删除之前的登陆信息
        String oldToken = (String) memcachedClient.get(user_token + user.getId());
        memcachedClient.delete(token_key + oldToken);
        //保存用户的token
        memcachedClient.set(token_key + token,0 , user);
        memcachedClient.set(user_token + user.getId(),0, token);
    }
}
